package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.constant.BsCommentConstants;
import com.ruoyi.common.constant.BsRelationConstants;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.BsStrategy;
import com.ruoyi.system.domain.dto.UserBaseInfoDTO;
import com.ruoyi.system.domain.ro.BsStrategyRO;
import com.ruoyi.system.domain.vo.BsStrategyVO;
import com.ruoyi.system.mapper.BsStrategyMapper;
import com.ruoyi.system.service.IBsCommentService;
import com.ruoyi.system.service.IBsRelationService;
import com.ruoyi.system.service.IBsStrategyService;
import com.ruoyi.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 攻略游记Service业务层处理
 *
 * @author ruoyi
 * @date 2023-11-25
 */
@RequiredArgsConstructor
@Service
public class BsStrategyServiceImpl implements IBsStrategyService {

    private final BsStrategyMapper baseMapper;
    private final ISysUserService iSysUserService;
    private final IBsRelationService iBsRelationService;
    private final IBsCommentService iBsCommentService;

    /**
     * 查询攻略游记
     */
    @Override
    public BsStrategyVO queryInfoAndAuthorById(Long id) {
        BsStrategy bsStrategy = baseMapper.selectById(id);
        BsStrategyVO bsStrategyVO = new BsStrategyVO();
        if (bsStrategy != null) {
            //创建人信息
            UserBaseInfoDTO userBaseInfoDTO = iSysUserService.selectUserBaseInfo(bsStrategy.getCreateById(), true);
            BeanUtil.copyProperties(bsStrategy, bsStrategyVO);
            bsStrategyVO.setCreateUserInfo(userBaseInfoDTO);
            //点赞 收藏
            Integer strategyLikeNum = iBsRelationService.getTotalRelationByType(BsRelationConstants.strategy_like, bsStrategy.getId().toString());
            bsStrategyVO.setStrategyLikeNum(strategyLikeNum);
            Integer strategyCollectNum = iBsRelationService.getTotalRelationByType(BsRelationConstants.strategy_collect, bsStrategy.getId().toString());
            bsStrategyVO.setStrategyCollectNum(strategyCollectNum);
            //评论总数
            Integer totalCommentByType = iBsCommentService.getTotalCommentByType(BsCommentConstants.TYPE_STRATEGY, bsStrategy.getId().toString());
            bsStrategyVO.setStrategyCommentNum(totalCommentByType);
            //是否点赞
            Map<String, Boolean> relationByTypeLike = iBsRelationService.getRelationByType(BsRelationConstants.strategy_like, Collections.singleton(bsStrategy.getId().toString()));
            if (!relationByTypeLike.isEmpty()) {
                if (ObjectUtil.isNotNull(relationByTypeLike.get(bsStrategy.getId().toString()))) {
                    bsStrategyVO.setCheckLike(relationByTypeLike.get(bsStrategy.getId().toString()));
                }
            }
            //是否收藏
            Map<String, Boolean> relationByTypeCollect = iBsRelationService.getRelationByType(BsRelationConstants.strategy_collect, Collections.singleton(bsStrategy.getId().toString()));
            if (!relationByTypeCollect.isEmpty()) {
                if (ObjectUtil.isNotNull(relationByTypeCollect.get(bsStrategy.getId().toString()))) {
                    bsStrategyVO.setCheckCollect(relationByTypeCollect.get(bsStrategy.getId().toString()));
                }
            }
        }
        return bsStrategyVO;
    }

    /**
     * 查询攻略游记
     */
    @Override
    public BsStrategy queryById(Long id) {
        BsStrategy bsStrategy = baseMapper.selectById(id);
        if (bsStrategy != null) {
            UserBaseInfoDTO userBaseInfoDTO = iSysUserService.selectUserBaseInfo(bsStrategy.getCreateById(), false);
            bsStrategy.setCreateUserInfo(userBaseInfoDTO);
        }
        return bsStrategy;
    }

    /**
     * 查询攻略游记列表
     */
    @Override
    public List<BsStrategy> queryPageList(BsStrategyRO ro) {
        LambdaQueryWrapper<BsStrategy> lqw = buildQueryWrapper(ro);
        List<BsStrategy> list = baseMapper.selectList(lqw);
        Set<Long> userIds = list.stream().map(BsStrategy::getCreateById).collect(Collectors.toSet());
        Map<Long, UserBaseInfoDTO> userMap = iSysUserService.selectUserBaseInfo(userIds);
        list.forEach(f -> {
            f.setCreateUserInfo(userMap.get(f.getCreateById()));
        });
        return list;
    }

    /**
     * 1.攻略-关注-关注人发布的-攻略游记列表-按审核通过时间排序\n" +
     * 2.攻略-推荐-攻略列表（按收藏数排序的-攻略游记列表）\n" +
     * 3.攻略-最新-按审核时间排序的-攻略游记列表\n" +
     * 4.我的-点赞-当前登录人点赞的-攻略游记列表-按审核通过时间排序的\n" +
     * 5.我的-收藏-当前登录人收藏的-攻略游记列表-按审核通过时间排序的\n" +
     * 6.我的-发布-当前登录人我的页面-发布按钮-按创建时间排序的"
     */
    @Override
    public List<BsStrategy> queryListByScene(String scene, String auditStatus, String title) {
        List<BsStrategy> result = new ArrayList<>();
        Long userId = SecurityUtils.getUserId();
        switch (scene) {
            case "1":
                result = baseMapper.selectListByRelationAttention(userId, BsRelationConstants.customer_attention, title);
                break;
            case "2":
                result = baseMapper.selectListByCollectTotal(title);
                break;
            case "3":
                result = baseMapper.selectList(new QueryWrapper<BsStrategy>().lambda()
                        .like(StrUtil.isNotBlank(title), BsStrategy::getTitle, title)
                        .eq(BsStrategy::getAuditStatus, 1)
                        .orderByDesc(BsStrategy::getAuditTime));
                break;
            case "4":
                result = baseMapper.selectListByRelation(userId, BsRelationConstants.strategy_like);
                break;
            case "5":
                result = baseMapper.selectListByRelation(userId, BsRelationConstants.strategy_collect);
                break;
            case "6":
                result = baseMapper.selectList(new QueryWrapper<BsStrategy>().lambda()
                        .eq(BsStrategy::getCreateById, userId)
                        .eq(StrUtil.isNotBlank(auditStatus), BsStrategy::getAuditStatus, auditStatus)
                        .orderByDesc(BsStrategy::getCreateTime)
                );
                break;
            default:
                result = new ArrayList<>();
        }
        //点赞统计
        Set<String> collect = result.stream().map(f -> String.valueOf(f.getId())).collect(Collectors.toSet());
        Map<String, Integer> map = iBsRelationService.getTotalRelationByType(BsRelationConstants.strategy_like, collect);
        //创建人信息
        Set<Long> userIds = result.stream().map(BsStrategy::getCreateById).collect(Collectors.toSet());
        Map<Long, UserBaseInfoDTO> userMap = iSysUserService.selectUserBaseInfo(userIds);
        //是否点赞
        Map<String, Boolean> relationByTypeLike = iBsRelationService.getRelationByType(BsRelationConstants.strategy_like, collect);
        //是否收藏
        Map<String, Boolean> relationByTypeCollect = iBsRelationService.getRelationByType(BsRelationConstants.strategy_collect, collect);

        //遍历分页
        result.forEach(f -> {
            f.setStrategyLikeNum(0);
            if (map.containsKey(String.valueOf(f.getId()))) {
                f.setStrategyLikeNum(map.get(String.valueOf(f.getId())));
            }
            f.setCreateUserInfo(userMap.get(f.getCreateById()));
            if (!relationByTypeLike.isEmpty()) {
                if (ObjectUtil.isNotNull(relationByTypeLike.get(f.getId().toString()))) {
                    f.setCheckLike(relationByTypeLike.get(f.getId().toString()));
                }
            }
            if (!relationByTypeCollect.isEmpty()) {
                if (ObjectUtil.isNotNull(relationByTypeCollect.get(f.getId().toString()))) {
                    f.setCheckCollect(relationByTypeCollect.get(f.getId().toString()));
                }
            }
        });
        return result;
    }

    /**
     * 查询攻略游记列表
     */
    @Override
    public List<BsStrategy> queryList(BsStrategyRO ro) {
        LambdaQueryWrapper<BsStrategy> lqw = buildQueryWrapper(ro);
        return baseMapper.selectList(lqw);
    }

    private LambdaQueryWrapper<BsStrategy> buildQueryWrapper(BsStrategyRO ro) {
        Map<String, Object> params = ro.getParams();
        LambdaQueryWrapper<BsStrategy> lqw = Wrappers.lambdaQuery();
        lqw.eq(ro.getCreateById() != null, BsStrategy::getCreateById, ro.getCreateById());
        lqw.like(StringUtils.isNotBlank(ro.getTitle()), BsStrategy::getTitle, ro.getTitle());
        lqw.eq(StringUtils.isNotBlank(ro.getContent()), BsStrategy::getContent, ro.getContent());
        lqw.eq(StringUtils.isNotBlank(ro.getImg()), BsStrategy::getImg, ro.getImg());
        lqw.eq(StringUtils.isNotBlank(ro.getAuditStatus()), BsStrategy::getAuditStatus, ro.getAuditStatus());
        lqw.between(params.get("beginCreateTime") != null && StringUtils.isNotBlank(params.get("beginCreateTime").toString()) && params.get("endCreateTime") != null && StringUtils.isNotBlank(params.get("endCreateTime").toString()),
                BsStrategy::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
        return lqw;
    }

    /**
     * 新增攻略游记
     */
    @Override
    public Boolean insertByBo(BsStrategyRO ro) {
        BsStrategy add = BeanUtil.toBean(ro, BsStrategy.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            ro.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改攻略游记
     */
    @Override
    public Boolean updateByBo(BsStrategyRO ro) {
        BsStrategy update = BeanUtil.toBean(ro, BsStrategy.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(BsStrategy entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除攻略游记
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
